package com.example.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.common.common.config.filter.UserInfo;

import java.util.Date;

/**
 * @author qwer3
 * @version 1.0.0
 * @create 2025/10/30 21:30
 */
public class JwtUtils {

    // JWT 签名密钥（生产环境请从配置文件读取！）
    private static final String SECRET = "your-256-bit-secret"; // 建议至少 32 字节
    private static final long EXPIRATION = 24 * 60 * 60 * 1000; // 2 小时（毫秒）

    private static final Algorithm algorithm = Algorithm.HMAC256(SECRET);

    /**
     * 生成 JWT Token
     *
     * @param userId   用户ID
     * @param username 用户名
     * @return JWT 字符串
     */
    public static String generateToken(String userId, String username, String sessionId) {
        // 生成唯一 nonce，确保即使 userId/username 相同，token 也不同
        String nonce = java.util.UUID.randomUUID().toString();

        Date now = new Date();
        Date expireTime = new Date(now.getTime() + EXPIRATION);

        return JWT.create()
                .withSubject("user-auth")           // 主题
                .withIssuedAt(now)                  // 签发时间
                .withExpiresAt(expireTime)          // 过期时间
                .withClaim("userId", userId)        // 自定义声明
                .withClaim("username", username)
                .withClaim("sessionId", sessionId)
                .withClaim("nonce", nonce)          // ✅ 关键：确保唯一性
                .withJWTId(java.util.UUID.randomUUID().toString()) // 标准 jti（可选）
                .sign(algorithm);
    }

    /**
     * 验证并解析 JWT
     *
     * @param token JWT 字符串
     * @return DecodedJWT 对象（可从中获取 userId, username 等）
     * @throws JWTVerificationException 验证失败时抛出
     */
    public static DecodedJWT verifyToken(String token) throws JWTVerificationException {
        return JWT.require(algorithm)
                .build()
                .verify(token);
    }

    /**
     * 从 Token 中安全获取用户信息（可选封装）
     */
    public static UserInfo getUserInfoFromToken(String token) {
        DecodedJWT jwt = verifyToken(token);
        return new UserInfo(
                jwt.getClaim("userId").asString(),
                jwt.getClaim("username").asString()
        );
        // nonce 不需要返回给业务层
    }

    public static String getSessionIdFromToken(String token) {
        DecodedJWT jwt = verifyToken(token);
        return jwt.getClaim("sessionId").asString();
    }
}